package com.klm.config.interceptor;

import com.alibaba.fastjson2.JSONObject;
import com.klm.annotation.Translate;
import com.klm.annotation.TranslateFromField;
import com.klm.annotation.TranslateToField;
import com.klm.client.TranslateClient;
import com.klm.config.local.TranslateThreadLocal;
import com.klm.common.constant.BaseConstant;
import com.klm.enumeration.LangCodeEnum;
import com.klm.model.ComLangContentModel;
import com.klm.model.ComLangModel;
import com.klm.request.GetFullContentRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.*;

/**
 * mybatis 查询结果list拦截器，自动翻译查询结果中的字段值
 */
@Slf4j
@Intercepts({
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
@Component
@ConditionalOnBean(StringRedisTemplate.class)
public class TranslateSelectInterceptor implements Interceptor {

    @Autowired
    private TranslateClient client;

    /**
     * Redis中存储语言包的key值 FW:LANG:SYS:item_key
     */
    private static final String REDIS_KEY_LANG_PREFIX = "FW:LANG:SYS:";

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 执行原方法，获取结果
        Object result = invocation.proceed();

        // 如果不是我们处理的包，直接返回结果
        if (result == null) {
            return result;
        }

        // 首先检查 result 是否是 List 类型
        if (result instanceof List) {
            List<?> list = (List<?>) result;
            for (Object item : list) {
                translateItem(item);
            }
        } else {
            translateItem(result);
        }
        return result;
    }

    private void translateItem(Object item) {
        if (item == null) {
            return;
        }

        Class<?> clazz = item.getClass();
        // 检查类是否有 @Translate 注解
        if (!clazz.isAnnotationPresent(Translate.class)) {
            return;
        }

        // 获取所有字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            // 检查字段是否有 @TranslateFromField 注解
            if (field.isAnnotationPresent(TranslateFromField.class)) {
                try {
                    Object value = field.get(item);
                    if (value != null) {
                        translateField(item, field, value);
                    }
                } catch (IllegalAccessException e) {
                    log.error("[Trans. plugin] Translate field error", e);
                }
            }
        }
    }

    private void translateField(Object item, Field fromField, Object value) {
        Class<?> clazz = item.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            // 检查字段是否有 @TranslateToField 注解
            if (field.isAnnotationPresent(TranslateToField.class)) {
                TranslateToField annotation = field.getAnnotation(TranslateToField.class);
                String fromFieldName = annotation.fromField();
                if (fromField.getName().equals(fromFieldName)) {
                    try {
                        String translatedValue = getLangContentByItemKey(value.toString());
                        field.set(item, translatedValue);
                    } catch (IllegalAccessException e) {
                        log.error("[Trans. plugin] Set translated field error", e);
                    }
                    break;
                }
            }
        }
    }

    private String getLangContentByItemKey(String itemKey) {

        Map<String, String> map = TranslateThreadLocal.get();
        String langCode = map.get(BaseConstant.ThreadLocal.TRAN_LANG_CODE);
        if (langCode == null) {
            langCode = LangCodeEnum.EN.getLangCode();
        }

        String cacheKey = REDIS_KEY_LANG_PREFIX + itemKey;
        log.debug("[Trans. plugin] 多語言自動翻譯器：cacheKey: " + cacheKey);
        // 获取缓存
        GetFullContentRequest request = new GetFullContentRequest();
        request.setServerUrl("http://localhost:8080");
        request.setItemKey(itemKey);
        ComLangModel comLangModel = client.executeRequest(request, HttpMethod.POST, ComLangModel.class);
        try {
            log.debug("[Trans. plugin] 多語言自動翻譯器：cacheContent: {}",JSONObject.toJSONString(comLangModel));
        } catch (Exception e) {
            log.error("[Trans. plugin] 多語言自動翻譯器：cacheContent解析异常",e);
        }

        if (comLangModel != null) {
            List<ComLangContentModel> contentList = comLangModel.getContentList();
            String finalLangCode = langCode;
            if (contentList.isEmpty()) {
                log.warn("[Trans. plugin] 多語言自動翻譯器：找不到語言代碼: " + finalLangCode + " 的翻譯內容");
                return "";
            }
            return contentList.stream()
                    .filter(model -> finalLangCode.equals(model.getLangCode()))
                    .map(ComLangContentModel::getLanguageContent)
                    .findFirst()
                    .orElse(null);
        }
        return itemKey;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // 可以接收配置的属性
    }
}

